/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dxfpresentation;

import vtk.*;

/**
 *
 * @author adriano
 */
public class GeometryBuilder {
    private vtkPolyData baseGeometry;
    private vtkPolyDataCollection pdCollection;
    private vtkBooleanOperationPolyDataFilter booleanOperationPdFilter;
    private vtkAppendPolyData pdAppender;
    private vtkCleanPolyData cleaner;
    
    public GeometryBuilder() {
        LoadVTKLibraries();
        pdCollection = new vtkPolyDataCollection();
        pdAppender = new vtkAppendPolyData();
    }
    
     /**
     * @return the baseGeometry
     */
    public vtkPolyData getBaseGeometry() {
        return baseGeometry;
    }

    /**
     * @param baseGeometry the baseGeometry to set
     */
    public void setBaseGeometry(vtkPolyData baseGeometry) {
        this.baseGeometry = baseGeometry;
    }
    
    public vtkPolyData getPolyData() {        
        return baseGeometry;
    }
    
    public vtkPolyDataCollection getPdCollection() {
        return pdCollection;
    }
    
    public void addPolyData(vtkPolyData polyData) {
        pdCollection.AddItem(polyData);
    }
    
    public void appendPolyData(vtkPolyData polyData) {
        pdAppender.AddInput(polyData);
        pdAppender.Update();
        int GetNumberOfCells = pdAppender.GetOutput().GetNumberOfCells();
        int GetNumberOfPoints = pdAppender.GetOutput().GetNumberOfPoints();
        int GetNumberOfVerts = pdAppender.GetOutput().GetNumberOfVerts();
        int GetNumberOfPolys = pdAppender.GetOutput().GetNumberOfPolys();
        
        cleaner = new vtkCleanPolyData();
        cleaner.SetInputConnection(pdAppender.GetOutputPort());
        cleaner.PointMergingOn();
        cleaner.Update();
        int GetNumberOfCells1 = cleaner.GetOutput().GetNumberOfCells();
        int GetNumberOfPoints1 = cleaner.GetOutput().GetNumberOfPoints();
        int GetNumberOfVerts1 = cleaner.GetOutput().GetNumberOfVerts();
        int GetNumberOfPolys1 = cleaner.GetOutput().GetNumberOfPolys();
        
        int r = 0;
    }
       
    public void applyDifferenceOperation() {
        int numberOfItems = pdCollection.GetNumberOfItems();
        
        for (int i = 1; i < numberOfItems; i++) {
            vtkPolyData polyData1 = triangulatePolyData(baseGeometry);     
            vtkPolyData polyData2 = triangulatePolyData((vtkPolyData)pdCollection.GetItemAsObject(i));
            
            booleanOperationPdFilter = new vtkBooleanOperationPolyDataFilter();
            booleanOperationPdFilter.SetOperationToDifference();
            
            booleanOperationPdFilter.AddInput(0, polyData1);
            booleanOperationPdFilter.AddInput(1, polyData2);
            booleanOperationPdFilter.Update();
            
            baseGeometry.Delete();
            baseGeometry = new vtkPolyData();
            baseGeometry = booleanOperationPdFilter.GetOutput();
            
            booleanOperationPdFilter.Delete();
        }
        
        pdCollection.RemoveAllItems();
        pdCollection.AddItem(baseGeometry);
        setMaterial(1.4629);
    } 
    
    public void setMaterial(double dieletric) {
        //triangulatedCylinder = triangulatePolyData(cylinderSource.GetOutput());
        int nrOfCells = baseGeometry.GetNumberOfCells(); 
        vtkDoubleArray scalars = new vtkDoubleArray();
        scalars.SetName("silicio");
        scalars.SetNumberOfComponents(1);
        scalars.SetNumberOfValues(nrOfCells);
        
        for (int i = 0; i < nrOfCells; i++) {
            scalars.SetValue(i, dieletric);
        }
        
        baseGeometry.GetCellData().SetScalars(scalars);
        baseGeometry.Modified();
    }
    
    public void applyUnionOperation() {
        int numberOfItems = pdCollection.GetNumberOfItems();
        
        for (int i = 1; i < numberOfItems; i++) {
            vtkPolyData polyData1 = triangulatePolyData(baseGeometry);     
            vtkPolyData polyData2 = triangulatePolyData((vtkPolyData)pdCollection.GetItemAsObject(i));
            
            booleanOperationPdFilter = new vtkBooleanOperationPolyDataFilter();
            booleanOperationPdFilter.SetOperationToIntersection();
            
            booleanOperationPdFilter.AddInput(0, polyData1);
            booleanOperationPdFilter.AddInput(1, polyData2);
            booleanOperationPdFilter.Update();
            
            baseGeometry.Delete();
            baseGeometry = new vtkPolyData();
            baseGeometry = booleanOperationPdFilter.GetOutput();
            
            booleanOperationPdFilter.Delete();
        }
    }
     
    private vtkPolyData triangulatePolyData(vtkPolyData polydata) {
        vtkTriangleFilter triangulator = new vtkTriangleFilter();
        triangulator.SetInput(polydata);
        triangulator.Update();
        
        return triangulator.GetOutput();
    }
    
    private static void LoadVTKLibraries() {       
        System.loadLibrary("vtkCommon");
        System.loadLibrary("vtkFiltering");
        System.loadLibrary("vtkGenericFiltering");      
        System.loadLibrary("vtkCommonJava");
        System.loadLibrary("vtkFilteringJava");
        System.loadLibrary("vtkGenericFilteringJava");
    }
}
